package com.cskaoyan.javase.oop3._0abstract._3exercise;

import sun.security.x509.AVA;

/**
 * 编码练习
 * 公司正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 * 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 *      1.普通员工包含3个属性：姓名、工号以及工资，行为是工作
 *      2.程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 *      3.经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 * 请使用所学的知识设计该员工系统
 * 要求类中提供必要的方法进行属性访问（description）
 *
 * 如果仅考虑成员的复用,可以用普通员工做父类,但这肯定不行,原因如下:
 *      1.从程序的长远发展来说,普通员工完全有可能增加一些成员,这时就不合理了
 *          既然程序中存在普通员工这个对象,那么它就不适合作为父类
 *      2.用普通类做父类,虽然也能复用成员,但是相比较于抽象类,少了抽象方法
 *          抽象方法可以起着"占位"的作用,起着"制定标准,规范"的作用
 * 抽象类在程序体系当中,不存在它的对象,对它的修改应该考虑每一个子类,这样能够更好的做程序设计.
 *
 * @since 14:55
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 创建对象,测试
        BaseStaff bs;
        bs = new NormalStaff("张三", 1, 10000);
        bs.work();
        bs.printStaff();


        bs = new Coder("李四", 2, 50000);
        if (bs instanceof Coder) {
            Coder c = (Coder) bs;
            c.overTimeWork();
        }
        bs.printStaff();
        bs.work();


        bs = new Manager("王二", 3, 100000, 1000000);
        bs.work();
        if (bs instanceof Manager) {
            Manager m = (Manager) bs;
            System.out.println(m.bonus);
        }
        bs.printStaff();
    }
}

// 抽象的员工父类
abstract class BaseStaff {
    String name;
    int staffId;
    double salary;

    public BaseStaff(String name, int staffId, double salary) {
        this.name = name;
        this.staffId = staffId;
        this.salary = salary;
    }

    public abstract void work();

    // 如果子类有共同需要一个方法的需求,这时可以把该方法的实现写在抽象类中,子类如果觉得OK,就直接继承并使用,子类如果觉得不行,那就自己重写
    public void printStaff() {
        System.out.println("职工号为" + staffId + "的员工,姓名是" + name + ",Ta的月工资是" + salary);
    }

}

class NormalStaff extends BaseStaff {
    public NormalStaff(String name, int staffId, double salary) {
        super(name, staffId, salary);
    }

    @Override
    public void work() {
        System.out.println("负责杂项工作~");
    }
}

class Coder extends BaseStaff {
    public Coder(String name, int staffId, double salary) {
        super(name, staffId, salary);
    }

    @Override
    public void work() {
        System.out.println("负责写Bug~");
    }

    // 子类独有行为
    public void overTimeWork() {
        System.out.println("每天加班,蹭公司的空调和网");
    }
}

class Manager extends BaseStaff {
    // 子类独有属性
    double bonus;

    public Manager(String name, int staffId, double salary, double bonus) {
        super(name, staffId, salary);
        this.bonus = bonus;
    }

    @Override
    public void printStaff() {
        System.out.println("职工号为" + staffId + "的员工,姓名是" + name + ",Ta的月工资是" + salary + ",除此之外,Ta每年还有" + bonus + "的奖金~~");
    }

    @Override
    public void work() {
        System.out.println("负责指挥人干活~");
    }
}